package com.test.jni.service;

import com.sun.jna.Library;
import com.sun.jna.Structure;
import lombok.Data;

import java.util.Arrays;
import java.util.List;

/**
 * 定义一个接口，默认的是继承Library ，如果动态链接库里的函数是以stdcall方式输出的，那么就继承StdCallLibrary
 * 这个接口对应一个动态链接(SO)文件
 */
public interface LibraryStruct extends Library {

    // 定义结构体类，对应结构体Teacher
    @Data
    class TeacherStruct extends Structure {
        //结构体参数类型及顺序要严格按照C结构体的类型及顺序
        public int tea_age;
        public String tea_name;

        // 定义值传递和指针传递类
        public static class ByReference extends TeacherStruct implements Structure.ByReference {
            //指针和引用的传递使用ByReference
        }

        public static class ByValue extends TeacherStruct implements Structure.ByValue {
            //拷贝参数传递使用ByValue
        }

        /**
         * 重写getFieldOrder获取字段列表, 很重要，没有会报错
         */
        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("tea_age", "tea_name");
        }
    }

    // 定义结构体类，对应结构体 Student
    @Data
    class StudentStruct extends Structure {
        //结构体参数类型及顺序要严格按照C结构体的类型及顺序
        public int stu_age;
        public String stu_name;

        // 定义值传递和指针传递类
        public static class ByReference extends StudentStruct implements Structure.ByReference {
            //指针和引用的传递使用ByReference
        }

        public static class ByValue extends StudentStruct implements Structure.ByValue {
            //拷贝参数传递使用ByValue
        }

        /**
         * 重写getFieldOrder获取字段列表, 很重要，没有会报错
         */
        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("stu_age", "stu_name");
        }
    }

    // 定义一个函数对应C、C++的函数。指针(地址)结构体参数用ByReference，值结构体参数用ByValue
    // 返回直接用值参数就可以
    TeacherStruct.ByValue stuTea(StudentStruct.ByValue stu, TeacherStruct.ByReference tea);
}
